最近又出現一些新的狀況,主要是因為 Android 的 Shared Preferences 不太可靠的關係。
而且我們主要目標對象是公車站牌(Android 板子),希望有遠端更新,遠端操作…。
並期望放出就能自主活得好好滴。
但是存放在 Shared Preferences 的站牌ID,就隨著多次操作後就跟著 Shared Preferences 一同消失了!
可以參考下面這篇:
在他們的例子,會有將近 0.2% ~ 0.3% 使用者的 Shared Preferences 會遺失掉。
推薦的解決方式是使用 DB。
於是我們也就緊急發佈出 DB 版本。
但是已經消失的該怎麼辦哩??
於是將矛頭轉到 GCM,但是聽說要使用 GCM 的必須登入 Google Account。
此時心想不太對,因為外面站牌都未登入 Google,雖然「再」大痛一次,就可以玩更多花樣,也預期能比較好維護。
所以還先看一下使用限制會比較保險:
最低要求,GCM 需要執行在Android版本 2.2 以上且同時安裝Google Play Store APP
,
如果你想要透過Google Play Services
使用GCM的新功能,Device 需要執行在Android版本 2.3 以上
在pre-3.0 需要設定 Google Account,但是 4.0.4 以後可以不用設定 Google Account
看完不用 Google Account 終於鬆了一口氣。
在實驗的過程中,發現 GCM 需要 Google Play Services,然後得去 Google Store 設定帳號下載。
PS :不過可以事先把 Google Play Services
APP dump 出來,然後直接安裝也算。
接著主要參考下面兩篇,實作GCM:
build.gradle 1 2 3 dependencies { compile "com.google.android.gms:play-services:7.0.0" }
Android SDK(GCM) 1 2 3 4 5 6 id: 126 or "extra-android-m2repository" Type: Extra Desc: Android Support Repository, revision 13 id: 127 or "extra-android-support" Type: Extra Desc: Android Support Library, revision 22.1
1 2 3 4 5 6 7 8 9 10 11 12 13 <uses-permission android:name ="com.google.android.c2dm.permission.RECEIVE" /> <application > <receiver android:name =".MyReceiver" android:exported ="true" android:permission ="com.google.android.c2dm.permission.SEND" > <intent-filter > <action android:name ="com.google.android.c2dm.intent.RECEIVE" /> <category android:name ="YOUR_PACKAGE_NAME" /> </intent-filter > </receiver > </application >
當 GCM 傳送訊息給你的 app 時, BroadcastReceiver 會收到訊息(intent),你的可以在 BroadcastReceiver 處理這條 intent,或者交給 Service 處理(通常是IntentService)。
如果你用 Service 的話,你的 BroadcastReceiver 需繼承自 WakefulBroadcastReceiver, to hold a wake lock while the service is doing its work
GcmBroadcastReceiver.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.util.Log;import com.google.android.gms.gcm.GoogleCloudMessaging;public class GcmBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "GCM" ; @Override public void onReceive (Context context, Intent intent) { Log.i(TAG, "GcmBroadcastReceiver" ); GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context); String messageType = gcm.getMessageType(intent); Log.i(TAG, "GcmBroadcastReceiver messageType:" +messageType); Bundle extras = intent.getExtras(); if (!extras.isEmpty()) { if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) { } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) { } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) { Log.i(TAG,"Message GET" ); } Log.i(TAG, "GcmBroadcastReceiver Received: " + extras.toString()); } } }
Server 端則先用 python。python-gcm